/*
 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

function simple_ctor0() {
}

function simple_ctor1() {
}

function simple_ctor2() {
}

function bimorphic_call_site(ctor_fun) {
    return new ctor_fun()
}

function megamorphic_call_site(ctor_fun) {
    return new ctor_fun()
}

function monomorphic_call_site_simple_ctor(ctor_fun) {
    return new ctor_fun()
}

function monomorphic_call_site_builtin_ctor() {
    return new Number(42)
}

class BaseClass {
}

class DerivedClass extends BaseClass {
}

function monomorphic_call_site_derived_ctor() {
    return new DerivedClass()
}

//! CHECKER      Expand new object dyn range using profiling info
//! RUN          options: "--compiler-hotness-threshold=10 --compiler-ecma-newobj-profiling=true --compiler-regex _GLOBAL::.*_call_site.*", entry: "_GLOBAL::func_main_0"
//! METHOD       "bimorphic_call_site"
//! PASS_AFTER   "Codegen"
//! INST         /Intrinsic.AllocDynObject.*/
//! INST         /Intrinsic.ResolveAllocResult.*/
//! INST         /Intrinsic.NewobjDynrangeHandled*/
//! METHOD       "megamorphic_call_site"
//! PASS_AFTER   "Codegen"
//! INST         /Intrinsic.AllocDynObject.*/
//! INST         /Intrinsic.ResolveAllocResult.*/
//! INST         /Intrinsic.NewobjDynrangeHandled*/
//! METHOD       "monomorphic_call_site_simple_ctor"
//! PASS_BEFORE  "InlineIntrinsics"
//! INST         /Intrinsic.AllocDynObject.*/
//! INST         /Intrinsic.ResolveAllocResult.*/
//! INST_NOT     /Intrinsic.NewobjDynrangeHandled*/
//! PASS_AFTER   "InlineIntrinsics"
//! INST         /Intrinsic.AllocDynObject.*/
//! INST_NOT     /Intrinsic.ResolveAllocResult.*/
//! INST_NOT     /Intrinsic.NewobjDynrangeHandled*/
//! METHOD       "monomorphic_call_site_derived_ctor"
//! PASS_AFTER   "Codegen"
//! INST_NOT     /Intrinsic.AllocDynObject.*/
//! INST         /Intrinsic.ResolveAllocResult.*/
//! INST_NOT     /Intrinsic.NewobjDynrangeHandled*/
//! METHOD       "monomorphic_call_site_builtin_ctor"
//! PASS_AFTER   "Codegen"
//! INST_NOT     /Intrinsic.AllocDynObject.*/
//! INST_NOT     /Intrinsic.ResolveAllocResult.*/
//! INST_NOT     /Intrinsic.NewobjDynrangeHandled*/
//! EVENT        /Deoptimization,.*monomorphic_call_site_simple_ctor.*,.*,IFRAME/
RuntimeTesting.PrepareFunctionForOptimization(bimorphic_call_site);
RuntimeTesting.PrepareFunctionForOptimization(megamorphic_call_site);
RuntimeTesting.PrepareFunctionForOptimization(monomorphic_call_site_simple_ctor);
RuntimeTesting.PrepareFunctionForOptimization(monomorphic_call_site_builtin_ctor);
RuntimeTesting.PrepareFunctionForOptimization(monomorphic_call_site_derived_ctor);

for (var i = 0; i < 10; ++i) {
    bimorphic_call_site(simple_ctor0)
    bimorphic_call_site(simple_ctor1)

    megamorphic_call_site(simple_ctor0)
    megamorphic_call_site(simple_ctor1)
    megamorphic_call_site(simple_ctor2)

    monomorphic_call_site_simple_ctor(simple_ctor0)

    monomorphic_call_site_builtin_ctor()

    monomorphic_call_site_derived_ctor()
}

RuntimeTesting.OptimizeFunctionOnNextCall(bimorphic_call_site);
RuntimeTesting.OptimizeFunctionOnNextCall(megamorphic_call_site);
RuntimeTesting.OptimizeFunctionOnNextCall(monomorphic_call_site_simple_ctor);
RuntimeTesting.OptimizeFunctionOnNextCall(monomorphic_call_site_builtin_ctor);
RuntimeTesting.OptimizeFunctionOnNextCall(monomorphic_call_site_derived_ctor);

for (var i = 0; i < 2; ++i) {
    bimorphic_call_site(simple_ctor0)
    bimorphic_call_site(simple_ctor1)

    megamorphic_call_site(simple_ctor0)
    megamorphic_call_site(simple_ctor1)
    megamorphic_call_site(simple_ctor2)

    monomorphic_call_site_simple_ctor(simple_ctor0)

    monomorphic_call_site_builtin_ctor()

    monomorphic_call_site_derived_ctor()
}

monomorphic_call_site_simple_ctor(simple_ctor1)